#include <iostream>
#include "brass.h"
using std::cout;
using std::cin;
using std::endl;
using std::string;

// format stuff
typedef std::ios_base::fmtflags format;
typedef std::streamsize precis;
format setFormat();
void restore(format f, precis p);


// Brass Methods
Brass::Brass(const std::string & s, long an, double bal): fullName(s), acctNum(an), balance(bal) {}

void Brass::ViewAcct() const
{
    format initialState = setFormat();
    precis prec = cout.precision(2);

    cout << "Client: " << fullName << endl;
    cout << "Account Number: " << acctNum << endl;
    cout << "Balance: $" << balance << endl;

    restore(initialState, prec);
}
void Brass::Withdraw(double amt)
{
    format initialState = setFormat();
    precis prec = cout.precision(2);

    if (amt < 0)
        cout << "取款不可以为负" << endl;
    else if (amt <= balance)
        balance -= amt;
    else
        cout << "取款金额超出余额" << endl;

    restore(initialState, prec);
}
void Brass::Deposit(double amt)
{
    if (amt < 0)
        cout << "存款不可以为负" << endl;
    else
        balance += amt; // ???
}
double Brass::Balance() const
{
    return balance;
}

// BrassPlus Methos
BrassPlus::BrassPlus(const string & s, long an, double bal, double ml, double r): Brass(s, an, bal), maxLoan(ml), owesBank(0.0), rate(r) {}
BrassPlus::BrassPlus(const Brass & ba, double ml, double r): Brass(ba), maxLoan(ml), owesBank(0.0), rate(r) {}

void BrassPlus::ViewAcct() const
{
    format initialState = setFormat();
    precis prec = cout.precision(2);

    Brass::ViewAcct();
    cout << "Maximum loan: $" << maxLoan << endl;
    cout << "Owed to bank: $" << owesBank << endl;
    cout.precision(3);
    cout << "Loan Rate: " << 100 * rate << "%" << endl;

    restore(initialState, prec);
}
void BrassPlus::Withdraw(double amt)
{
    format initialState = setFormat();
    precis prec = cout.precision(2);

    double bal = Balance();
    if (amt <= bal)
        Brass::Withdraw(amt);
    else if ( amt <= bal + maxLoan - owesBank)
    {
        double advance = amt - bal;
        owesBank += advance * (1.0 + rate);
        cout << "Bank advance: $" << advance << endl;
        cout << "Finance charge: $" << advance * rate << endl;
        Deposit(advance);
        Brass::Withdraw(amt);
    }
    else
        cout << "超出信用额度" << endl;
    
    restore(initialState, prec);
}

format setFormat()
{
    // set up ###.## format
    return cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
}

void restore(format f, precis p)
{
    cout.setf(f, std::ios_base::floatfield);
    cout.precision(p);
}